---
title: 'Annonce SWR 2.0'
image: https://assets.vercel.com/image/upload/v1670542323/swr/v2.png
description: 'Annonce SWR 2.0: Nouvelle API de mutation et amélioration des capacités de l’UI optimiste, nouveaux outils développeur, meilleur support du rendu simultané, et bien plus.'
date: 9 Décembre 2022
---

import { Callout } from 'nextra-theme-docs'
import { Bleed } from 'nextra-theme-docs'

import Authors, { Author } from 'components/authors'
import Video from 'components/video'

# Annonce SWR 2.0 [#announcing-swr-20]

<Authors date="9 Décembre 2022" by="par">
  <Author name="Shu Ding" link="https://twitter.com/shuding_" />
  <Author name="Jiachi Liu" link="https://twitter.com/huozhi" />
  <Author name="Toru Kobayashi" link="https://twitter.com/koba04" />
  <Author name="Yixuan Xu" link="https://twitter.com/yixuanxu94" />
</Authors>

Nous sommes heureux d’annoncer la release de SWR 2.0, la populaire librairie de récupération de données pour React qui permet aux composants de récupérer, mettre en cache et muter des données et de garder l’UI à jour avec les changements de ces données au fil du temps.

Cette nouvelle version vient avec de nombreuses améliorations et de nouvelles fonctionnalités, telles que de nouvelles API de mutation, des capacités d’UI optimiste améliorées, de nouveaux outils développeur et un meilleur support du rendu simultané. Nous souhaitons remercier chaleureusement tous les contributeurs et mainteneurs qui ont rendu cette release possible.

## Mutation et UI Optimiste [#mutation-and-optimistic-ui]

### useSWRMutation [#useswrmutation]

La mutation est une partie important du processus de récupération des données. Elles vous permettent de faire des changements dans vos données localement et à distance. Notre API `mutate` existante vous permet de revalider et de modifier vos données manuellement. Avec SWR 2.0, le nouveau hook `useSWRMutation` rend encore plus simple la modification des données à distance en utilisant une API déclarative. Vous pouvez configurer une mutation en utilisant le hook, et l’activer plus tard :

```jsx {11,16}
import useSWRMutation from 'swr/mutation'

async function sendRequest(url, { arg }) {
  return fetch(url, {
    method: 'POST',
    body: JSON.stringify(arg)
  })
}

function App() {
  const { trigger, isMutating } = useSWRMutation('/api/user', sendRequest)

  return (
    <button
      disabled={isMutating}
      onClick={() => trigger({ username: 'johndoe' })}
    >{
      isMutating ? 'Creation...' : 'Utilisateur Créé'
    }</button>
  )
}
```

L’exemple ci-dessus définit une mutation `sendRequest` qui affecte la ressource `’/api/user’`. Contrairement à `useSWR`, `useSWRMutation` ne démarre pas immédiatement la requête lors du rendu. Au lieu de cela, il retourne une fonction `trigger` qui peut être appelée plus tard pour démarrer manuellement la mutation.

La fonction `sendRequest` sera appelée lorsque le bouton sera cliqué, avec l’argument supplémentaire `{ username: ’johndoe’ }`. La valeur de `isMutating` sera définie sur `true` jusqu’à ce que la mutation soit terminée.

De plus, ce nouveau hook résout d’autres problèmes que vous pouvez rencontrer avec les mutations :

- Mise à jour optimiste de l’UI pendant que les données sont mutées
- Rétablisement automatique en cas d’échec de la mutation
- Éviter les éventuels problèmes de concurrence entre `useSWR` et d’autres mutations de la même ressource
- Alimenter le cache de `useSWR` après la fin de la mutation
- ...

Vous pouvez trouver des références d’API détaillées et des exemples en lisant la [documentation](/docs/mutation#useswrmutation) ou en parcourant les sections suivantes.

### UI Optimiste [#optimistic-ui]

L’UI Optimiste est un excellent modèle pour créer des sites web qui semblent rapides et réactifs ; cependant, il peut être difficile à implémenter correctement. SWR 2.0 a ajouté de nouvelles options puissantes pour le rendre plus facile.

Disons que nous avons une API qui ajoute un nouvel élément à une liste de tâches et l’envoie au serveur :

```jsx
await addNewTodo('New Item')
```

Dans notre UI, nous utilisons un hook `useSWR` pour afficher la liste de tâches, avec un bouton "Ajouter un nouvel élément" qui déclenche cette requête et demande à SWR de recharger les données via `mutate()` :

```jsx {7,8}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Afficher les donées */}</ul>

  <button onClick={async () => {
    await addNewTodo('Nouvel Element')
    mutate()
  }}>
    Ajouter un Nouvel Element
  </button>
</>
```

Cependant, la requête `await addNewTodo(...)` peut être très lente. Lorsqu’elle est en cours, les utilisateurs voient toujours l’ancienne liste même si nous pouvons déjà savoir à quoi ressemblera la nouvelle liste. Avec la nouvelle option `optimisticData`, nous pouvons afficher la nouvelle liste de manière optimiste, avant que le serveur ne réponde :

```jsx {8}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Afficher les donées */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Nouvel Element'), {
      optimisticData: [...data, 'Nouvel Element'],
    })
  }}>
    Ajouter un Nouvel Element
  </button>
</>
```

SWR va immédiatement mettre à jour les `data` avec la valeur `optimisticData`, et ensuite envoyer la requête au serveur. Une fois la requête terminée, SWR va revalider la ressource pour s’assurer qu’elle est à jour.

Comme beaucoup d’API, si la requête `addNewTodo(...)` nous renvoie les dernières données du serveur, nous pouvons directement afficher ce résultat (au lieu de démarrer une nouvelle revalidation) ! Il y a une nouvelle option `populateCache` pour dire à SWR de mettre à jour les données locales avec la réponse de la mutation :

```jsx {9}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Afficher les donées */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Nouvel Element'), {
      optimisticData: [...data, 'Nouvel Element'],
      populateCache: true,
    })
  }}>
    Ajouter un Nouvel Element
  </button>
</>
```

En même temps, nous n’avons plus besoin d’une nouvelle revalidation, car les données de réponse proviennent de la source de confiance, nous pouvons désactiver cet revalidation avec l’option `revalidate` :

```jsx {10}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Afficher les donées */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Nouvel Element'), {
      optimisticData: [...data, 'Nouvel Element'],
      populateCache: true,
      revalidate: false,
    })
  }}>
    Ajouter un Nouvel Element
  </button>
</>
```

Enfin, si `addNewTodo(...)` échoue avec une exception, nous pouvons rétablire les données optimistes (`[...data, 'Nouvel Element']`) que nous venons de définir, en définissant `rollbackOnError` sur `true` (qui est également l’option par défaut). Lorsque cela se produit, SWR va rétablir les `data` à la valeur précédente.

```jsx {11}
const { mutate, data } = useSWR('/api/todos')

return <>
  <ul>{/* Afficher les donées */}</ul>

  <button onClick={() => {
    mutate(addNewTodo('Nouvel Element'), {
      optimisticData: [...data, 'Nouvel Element'],
      populateCache: true,
      revalidate: false,
      rollbackOnError: true,
    })
  }}>
    Ajouter un Nouvel Element
  </button>
</>
```

Toutes ces options sont également disponibles dans le nouveau hook `useSWRMutation`. Pour en savoir plus, vous pouvez consulter notre [documentation](/docs/mutation#optimistic-updates). Et voici une démo montrant ce comportement :

<Video
  src="/video/optimistic-ui.mp4"
  caption="UI Optimiste avec rétablisement automatique en cas d’erreur"
  ratio={223/584}
/>

### Multiple Clé de Mutation [#mutate-multiple-keys]

L’API global `mutate` peut maintenant accepter une fonction de filtre, où vous pouvez muter ou revalider des clés spécifiques. Cela sera utile pour, par exemple, l’invalidation de toutes les données mises en cache. Pour en savoir plus, vous pouvez lire [Mutate Multiple Keys](/docs/mutation#mutate-multiple-items) dans la documentation.

```jsx
import { mutate } from 'swr'
// Ou depuis le hook si vous avez personnalisé votre fournisseur de cache:
// { mutate } = useSWRConfig()

// Mutation d’une seule ressource
mutate(key)

// Mutation de plusieurs ressources et effacement du cache (défini sur undefined)
mutate(
  key => typeof key === 'string' && key.startsWith('/api/item?id='),
  undefined,
  { revalidate: false }
)
```

## SWR Outils de Développement [#swr-devtools]

[SWRDevTools](https://swr-devtools.vercel.app) est une extention de navigateur qui vous aide à débugger votre cache SWR et les résultats de récupération. Consultez notre section [devtools](/docs/advanced/devtools) pour savoir comment utiliser les outils de développement dans votre application.

![](/img/devtools/cache-view.jpg)

## Prechargement des Données [#preloading-data]

Le préchargement des données peut améliorer considérablement l’expérience utilisateur. Si vous savez que la ressource sera utilisée plus tard dans l’application, vous pouvez utiliser la nouvelle API `preload` pour charger les données plus tôt :

```jsx {6}
import useSWR, { preload } from 'swr'

const fetcher = (url) => fetch(url).then((res) => res.json())

// Vous pouvez appeler la fonction preload n’importe où
preload('/api/user', fetcher)

function Profile() {
  // Le composant qui utilise les données:
  const { data, error } = useSWR('/api/user', fetcher)
  // ...
}

export function Page () {
  return <Profile/>
}
```

Dans cet exemple, l’API `preload` est appelée globalement. Cela signifie que que le prechargement des resources commence avant que React ne déclanche le rendu.
Et lorsque le composant `Profile` est rendu, les données peuvent probablement être disponibles. Si ce n’est pas le cas, le hook `useSWR` réutilisera la requête de prechargement en cours au lieu d’en démarrer une nouvelle.

L’API `preload` peut aussi être utilisée dans des cas comme le prechargement des données pour une autre page qui sera probablement rendue. Vous pouvez trouver plus d’informations sur le prechargement des données avec SWR [ici](/docs/prefetching).

## `isLoading` [#isloading]

`isLoading` est le nouvel état retourné par `useSWR`, qui indique **si la requête est toujours en cours et qu’aucune donnée n’a encore été chargée**. Précédemment, `isValidating` représentait à la fois l’état de chargement initial et l’état de revalidation. Il fallait donc vérifier si `data` et `error` étaient `undefined` pour déterminer s’il s’agissait de l’état de chargement initial.

Maintenant, c’est plus simple et vous pouvez utiliser directement la valeur `isLoading` pour afficher un message de chargement :

```jsx
import useSWR from 'swr'

function Profile() {
  const { data, isLoading } = useSWR('/api/user', fetcher)

  if (isLoading) return <div>chargement...</div>
  return <div>bonjour {data.name}!</div>
}
```

Notez que `isValidating` est toujours présent, vous pouvez donc toujours l’utiliser pour afficher un indicateur de chargement pour les revalidations.

<Callout emoji="📝">
  Nous avons ajouté la nouvelle page [Comprendre SWR](/docs/advanced/understanding) pour décrire comment SWR retourne les valeurs, ce qui inclut la différence entre `isValidating` et `isLoading`, et comment les combiner pour améliorer l’expérience utilisateur.
</Callout>

## Conservation de l’État Précédent [#preserving-previous-state]

L’option `keepPreviousData` est une nouvelle fonctionnalité qui vous permet de conserver les données qui ont été récupérées précédemment. Cela améliore considérablement l’expérience utilisateur lorsque vous récupérez des données en fonction d’actions utilisateur qui se produisent en temps réel, comme avec une fonction de recherche en direct, où la clé de la ressource change :

```jsx {5}
function Search() {
  const [search, setSearch] = React.useState('');

  const { data, isLoading } = useSWR(`/search?q=${search}`, fetcher, {
    keepPreviousData: true
  })

  return (
    <div>
      <input
        type="text"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        placeholder="Rechercher..."
      />

      <div className={isLoading ? "chargement" : ""}>
        {data?.products.map(item => <Product key={item.id} name={item.name} />)}
      </div>
    </div>
  );
}
```

<Video
  src="https://user-images.githubusercontent.com/3676859/163695903-a3eb1259-180e-41e0-821e-21c320201194.mp4"
  caption="Convervation des précédent résultat de recherche avec keepPreviousData activable"
  ratio={640/730}
/>

Allez voir le code sur [CodeSandbox](https://codesandbox.io/s/swr-keeppreviousdata-fsjz3m) et vous pouvez en lire plus à ce sujet [ici](/docs/advanced/understanding#return-previous-data-for-better-ux).

## Extension des Configurations [#extending-configurations]

`SWRConfig` peut maintenant accepter comme valeur une fonction. Lorsque vous avez plusieurs niveaux de `<SWRConfig>`, le niveau interne reçoit la configuration parent et retourne une nouvelle configuration. Ce changement rend la configuration de SWR plus flexible dans une grande codebase. Vous pouvez trouver plus d’informations [ici](/docs/global-configuration).

```jsx
<SWRConfig
  value={parentConfig => ({
    dedupingInterval: parentConfig.dedupingInterval * 5,
    refreshInterval: 100,
  })}
>
  <Page />
</SWRConfig>
```

## Amélioration du Support de React 18 [#improved-react-18-support]

SWR a été mis à jour pour utiliser les API `useSyncExternalStore` et `startTransition` de React 18. Celles-ci assurent une plus grande cohérence lors du rendu de l’UI simultanément. Ce changement ne nécessite aucune modification du code utilisateur et tous les développeurs en bénéficieront directement. Shims est inclus pour React 17 et les précédemment versions.

SWR 2.0 et toutes les nouvelles fonctionnalités sont toujours compatibles avec React 16 et 17.

## Guide de Migration [#migration-guide]

### La fonction de récupération n’accepte plus plusieurs paramètres [#fetcher-no-longer-accepts-multiple-arguments]

`key` est passé comme un seul argument.

```diff
- useSWR([1, 2, 3], (a, b, c) => {
+ useSWR([1, 2, 3], ([a, b, c]) => {
  assert(a === 1)
  assert(b === 2)
  assert(c === 3)
})
```

### La Mutation globale n’accept plus la fonction `getKey` [#global-mutate-no-longer-accepts-a-getkey-function]

Maintenant, si vous passez une fonction à la mutation globale, elle sera utilisée comme un [filtre](/blog/swr-v2#mutate-multiple-keys). Précédemment, vous pouviez passer une fonction qui renvoie une clé à la mutation globale :

```diff
- mutate(() => '/api/item') // une fonction qui revoie une clé
+ mutate('/api/item')       // pour transformer la clé, passez-la directement
```

### Nouvelle Propriété Requise `keys()` pour l’Interface Cache [#new-required-property-keys-for-cache-interface]

Quand vous utilisez votre propre implémentation de cache, l’interface Cache demande maintenant une méthode `keys()` qui retourne toutes les clés de l’objet cache, similaire aux instances JavaScript Map.

```diff
interface Cache<Data> {
  get(key: string): Data | undefined
  set(key: string, value: Data): void
  delete(key: string): void
+ keys(): IterableIterator<string>
}
```

### Modification de la Structure Interne du Cache [#changed-cache-internal-structure]

La structure interne des données du cache est un objet qui contient tous les états actuels.

```diff
- assert(cache.get(key) === data)
+ assert(cache.get(key) === { data, error, isValidating })

// getter
- cache.get(key)
+ cache.get(key)?.data

// setter
- cache.set(key, data)
+ cache.set(key, { ...cache.get(key), data })
```

<Callout emoji="🚨" type="error">
  Vous ne devriez pas écrire directement dans le cache, cela peut causer un comportement inprévisible.
</Callout>

### `SWRConfig.default` est renommé `SWRConfig.defaultValue` [#swrconfigdefault-is-renamed-as-swrconfigdefaultvalue]

`SWRConfig.defaultValue` est la propriété pour accéder à la configuration SWR par défaut.

```diff
- SWRConfig.default
+ SWRConfig.defaultValue
```

### Le Type `InfiniteFetcher` est renommé  `SWRInfiniteFetcher` [#type-infinitefetcher-is-renamed-as-swrinfinitefetcher]

```diff
- import type { InfiniteFetcher } from 'swr/infinite'
+ import type { SWRInfiniteFetcher } from 'swr/infinite'
```

### Evitez Suspense sur le Serveur [#avoid-suspense-on-server]

Si vous voulez utilisez `suspense: true` avec SWR côté serveur, incluant le pré-rendu dans Next.js, vous devez fournir des données initiales via [`fallbackData` ou `fallback`](/docs/with-nextjs#pre-rendering-with-default-data). Aujourd’hui, cela signifie que vous ne pouvez pas utiliser Suspense pour récupérer des données côté serveur. Vos deux autres options sont de faire de la récupération de données côté client ou de faire récupérer les données par votre framework (comme le fait `getStaticProps` dans Next.js).

### ES2018 comme cible de Build [#es2018-as-the-build-target]

Si vous voulez supporter IE 11, vous devez cibler ES5 dans votre framework ou votre bundler. Ce changement a permis une amélioration des performances sur le SSR, et garde la taille du bundle petite.

## Changelog [#changelog]

Lisez le Changelog complet [sur GitHub](https://github.com/vercel/swr/releases).

## Le Future & Merci ! [#the-future--thank-you]

Avec la sortie de [Next.js 13](https://nextjs.org/blog/next-13), nous voyons beaucoup de nouvelles choses passionnantes ainsi que des changements de paradigmes dans l’écosystème React : [React Server Components](https://beta.nextjs.org/docs/rendering/server-and-client-components), streaming SSR, [async components](https://beta.nextjs.org/docs/data-fetching/fetching#asyncawait-in-server-components), et le [`use` hook](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise). Beaucoup d’entre eux sont liés à la récupération de données, et certains d’entre eux ont des cas d’utilisation qui se chevauchent avec SWR.

Cependant, le bût du projet SWR reste le même. Nous voulons que cette librairie soit légère, indépendante de tout framework, et un peu _opinionated_ (i.e. revalider lors du focus). Au lieu d’essayer d’être une solution standard, nous voulons nous concentrer sur les innovations qui rendent l’UX meilleure. En attendant, nous faisons également des recherches sur la façon d’améliorer SWR avec ces nouvelles capacités de React.

Nous voulons aussi remercier tous les [143](https://github.com/vercel/swr/graphs/contributors) contributeurs (+ [106](https://github.com/vercel/swr-site/graphs/contributors) contributeurs de la documentation), ainsi que ceux qui nous ont aidé ou donné des retours. Un merci spécial à [Toru Kobayashi](https://twitter.com/koba04) pour tout son travail sur les outils développeur et la documentation - nous n’aurions pas pu le faire sans toi !
